import { defineComponent, ref, PropType, onMounted } from 'vue';
import { AntdComponentType, componentMap } from 'utils/components/index';
import { Form, Row, Col } from 'ant-design-vue';
export type ColumnType = 1 | 2 | 3 | 4;
export interface FormSchema {
  key: string;
  label: string;
  // modelValue: string | number | undefined | null;
  component: AntdComponentType;
  labelWidth?: string | number;
  wrapperWidth?: string | number;
  show?: any;
  rules?: any;
  props?: any;
  slots?: any;
}

export default defineComponent({
  name: 'YanForm',
  props: {
    modelValue: {
      type: Object as PropType<Recordable>,
      default: () => ({}),
    },
    schemas: {
      type: Array as PropType<FormSchema[]>,
      default: () => [],
    },
    column: {
      type: Number as PropType<ColumnType>,
      default: 2,
    },
    labelWidth: {
      type: [Number, String] as PropType<number | string>,
      default: 110,
    },
  },
  emits: ['handleGetFormRef'],

  setup(props, { emit }) {
    const formRef = ref(null);
    onMounted(() => {
      emit('handleGetFormRef', formRef);
    });

    return () => {
      const { modelValue } = props;
      const renderComponents = (schema: FormSchema) => {
        const { key, component, props: propsData, slots } = schema;
        const isCheck = ['Switch', 'Checkbox'].includes(component);
        const eventKey = 'onChange';
        const bindValue = {
          [isCheck ? 'checked' : 'value']: modelValue[key],
        };
        const on = {
          [eventKey]: (e: Nullable<Recordable>) => {
            const target = e ? e.target : null;
            const value = target ? (isCheck ? target.checked : target.value) : e;
            modelValue[key] = value;
          },
        };

        const componentsAttr: any = {
          ...on,
          ...bindValue,
          ...propsData,
        };
        const Comp = componentMap.get(component) as typeof defineComponent;

        return <Comp {...componentsAttr} style={{ width: '100%' }}></Comp>;
      };

      const renderLabelWidth = (w: string | number | undefined) => {
        let width = w || props.labelWidth;
        // if (width) {
        //   width = isNumber(width) ? `${width}px` : width;
        // }
        return {
          labelCol: { style: { width } },
          wrapperCol: { style: { width: `calc(100% - ${width})` } },
        };
      };

      const renderFormItems = () => {
        const { schemas, column } = props;
        const items = schemas.filter((schema) => schema.show !== false);
        const rows = new Array(Math.ceil(items.length / column)).fill(null);
        const cols = new Array(column).fill(null);
        return rows.map((_, row) => (
          <Row type="flex">
            {cols.map((_, col) => {
              const schema = items[row * column + col];
              if (schema) {
                const { key, label, rules, labelWidth } = schema;
                const { labelCol, wrapperCol } = renderLabelWidth(labelWidth);
                return (
                  <Col span={24 / column}>
                    <Form.Item
                      name={key}
                      style={{ paddingRight: '5px' }}
                      label={label}
                      labelCol={labelCol}
                      wrapperCol={wrapperCol}
                      rules={rules}
                    >
                      {renderComponents(schema)}
                    </Form.Item>
                  </Col>
                );
              }
              return null;
            })}
          </Row>
        ));
      };
      return <a-form labelAlign="right">{renderFormItems()}</a-form>;
    };
  },
});
